<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>ColumNav Documentation</title>
    <script type="text/javascript" src="./js/yui/yahoo.js"></script>
    <script type="text/javascript" src="./js/yui/event.js"></script>
    <script type="text/javascript" src="./js/yui/container_core.js"></script>
    <script type="text/javascript" src="./js/yui/dom.js"></script>
    <script type="text/javascript" src="./js/yui/animation.js"></script>
    <script type="text/javascript" src="./js/yui/connection.js"></script>
    <script type="text/javascript" src="./js/carousel.js"></script>
    <script type="text/javascript" src="./js/columnav.js"></script>
    <link href="./css/carousel.css" rel="stylesheet" type="text/css"/>
    <link href="./css/columnav.css" rel="stylesheet" type="text/css"/>
    <script type="text/javascript">
      try { document.execCommand('BackgroundImageCache', false, true); } catch(e) {}
      function init() {
          var cn_cfg = { prevElement: 'columnav-prev', source: 'contents.xml' };
          var cn = new YAHOO.extension.ColumNav('columnav', cn_cfg);
      }
      YAHOO.util.Event.addListener(window, 'load', init);
    </script>
    <link href="./css/stringify.css" rel="stylesheet" type="text/css"/>
  </head>
  <body>
    <div id="main">
      <div id="content">

        <h1>ColumNav</h1>

        <div class="prevButton">
          <a href="javascript:void(0)" id="columnav-prev">&lt; back</a>
        </div>
        <div id="columnav" class="carousel-component">
          <div class="carousel-clip-region">
            <ul class="carousel-list"></ul>
          </div>
        </div>

<!-- Markdown generated HTML begins here -->
<h2>Overview</h2>

<p>ColumNav is a hierarchical menu implementation utilizing Bill Scott's <a href="http://developer.yahoo.com/yui/">Yahoo UI</a> <a href="http://billwscott.com/carousel/">Carousel component</a>. Content is loaded from an unordered list (in the form of a DOM object) and displayed in a scrollable viewport, similar to Column View in the <a href="http://en.wikipedia.org/wiki/Image:Finder1.png">Mac OS X Finder</a>. Features include:</p>

<ul>
<li>infinite extensibility using Ajax to build sub-menus</li>
<li>a highly customizable look and feel using CSS</li>
<li>support for multiple columns</li>
<li>support for keyboard-only navigation (<kbd>CTRL</kbd> + arrow keys)</li>
<li>cross-browser compatibility</li>
</ul>

<h2>Examples</h2>

<p>The following examples demonstrate the three ways content can be loaded to initialize a ColumNav object:</p>

<ul>
<li><a href="examples/dom-source1.html">from a HTML list within the current page, via the DOM</a></li>
<li><a href="examples/dom-source2.html">from a DOM object built programmatically</a></li>
<li><a href="examples/url-source.html">from a DOM object acquired from an Ajax request</a></li>
</ul>

<p>Additional examples, demonstrating some customizations:</p>

<ul>
<li><a href="examples/infinite.html">Infinite depth</a>: unlimited sub-menus using Ajax</li>
<li><a href="examples/custom-icons.html">Custom icons</a>: using CSS to fine tune images</li>
<li><a href="examples/link-action.html">Link actions</a>: preprocessing clicks on leaf node links</li>
<li><a href="examples/multi-col.html">Multiple columns</a></li>
</ul>

<h2>Download</h2>

<ul>
<li><strong><a href="http://stringify.com/misc/columnav-0.9.4.zip">columnav-0.9.4.zip</a></strong> (21 Feb. 2007): includes source code, examples, and this documentation</li>
<li>the latest version can always be found <a href="http://stringify.com/columnav/">here</a></li>
</ul>

<h2>Usage</h2>

<p>Setting up ColumNav is a straightforward process of providing the proper HTML, JavaScript, and CSS configuration, along with creating the content source. Understanding how a content source is formed and processed is key to using ColumNav, so it is presented first below.</p>

<h3>Content sources</h3>

<p>As mentioned above, the ColumNav accepts a standard unordered list in the form of a DOM object. The list items contain simple links with optional attributes. For example:</p>

<pre><code>&lt;ul id="basketball-list"&gt;
  &lt;li&gt;
    &lt;a href="http://sports.yahoo.com/nba/"&gt;NBA&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;
        &lt;a href=""&gt;Atlantic&lt;/a&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href="http://sports.yahoo.com/nba/teams/bos"&gt;Boston Celtics&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href="http://sports.yahoo.com/nba/teams/njn"&gt;New Jersey Nets&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href="http://sports.yahoo.com/nba/teams/nyk"&gt;New York Knicks&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href="http://sports.yahoo.com/nba/teams/phi"&gt;Philadelphia 76ers&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href="http://sports.yahoo.com/nba/teams/tor"&gt;Toronto Raptors&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href="examples/ajax/ncaa/index.xml" rel="ajax"&gt;NCAA&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</code></pre>

<p>The whole structure is loaded into the ColumNav component, but broken down into "pages" corresponding to each item's position in the list. Top-level items are initially viewable (in this case, "NBA" and "NCAA"), with nested lists scrolling into view when their parent is clicked (sibling actually, but functional parent). In this example, when the "NBA" item is clicked, the next page scrolls into view. This page has a single item ("Atlantic") which, when clicked, brings its associated sub-list into view. These last items have no sub-lists, and serve as normal links. Note that <code>href</code> attributes on items with sub-lists will be ignored. Each link may also contain a <code>class</code> attribute useful for fine-grained CSS control (see below).</p>

<p>Of special note is the last item in the list ("NCAA"). This item does not have a sub-list but still produces one when clicked. That is because of its <code>rel="ajax"</code> attribute which tells the script to obtain the next list via Ajax using the URL provided in the <code>href</code>. If an item has both a sub-list <em>and</em> <code>rel="ajax"</code>, the sub-list will be preferred.</p>

<p><strong>Content sources loaded though Ajax should be served with a proper XML mime type</strong> (<code>application/xml</code> for example). Since the Ajax response will be treated as an XML DOM object, this is altogether appropriate. Moreover, some browsers will not allow for DOM processing of the response if it is received with a non-XML mime type (e.g. <code>text/html</code>).</p>

<h3>HTML</h3>

<p>The HTML structure of each ColumNav should conform to that expected by the Carousel component script:</p>

<pre><code>&lt;div id="mycolumnav" class="carousel-component"&gt;
  &lt;div class="carousel-clip-region"&gt;
    &lt;ul class="carousel-list"&gt;&lt;/ul&gt;
  &lt;/div&gt;
&lt;/div&gt;
</code></pre>

<p>The class names are required by the Carousel. See its <a href="http://billwscott.com/carousel/">documentation</a> for more information. The <code>id</code> value is arbitrary, and will be passed as the first argument to the ColumNav constructor (see below).</p>

<p>Additionally, you can provide a "back" button for retracing your steps:</p>

<pre><code>&lt;div class="prevButton"&gt;
  &lt;a href="javascript:void(0)" id="mycolumnav-prev"&gt;&amp;lt; back&lt;/a&gt;
&lt;/div&gt;
</code></pre>

<p>The HTML can be anything, provided the clickable element has an <code>id</code> attribute. The <code>id</code> will be passed to the ColumNav constructor to enable the button. A ColumNav instance can have multiple back buttons. See the configuration properties below.</p>

<h3>JavaScript</h3>

<p>ColumNav relies on Carousel, which in turn relies on the <a href="http://developer.yahoo.com/yui/">Yahoo UI Library</a> (version 0.12 or above). Include the required files in the <code>&lt;head&gt;</code> of your document:</p>

<pre><code>&lt;script type="text/javascript" src="yahoo.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="event.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="container_core.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="dom.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="animation.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="connection.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="carousel.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="columnav.js"&gt;&lt;/script&gt;
</code></pre>

<p>Since a ColumNav instance depends on the existence of an HTML element, it is best to instantiate it after page load. For instance:</p>

<pre><code>&lt;script type="text/javascript"&gt;
  function init() {
      // ... do other stuff first, perhaps ...
      var cn_cfg = { prevElement: 'mycolumnav-prev'', source: some_url_or_dom_object };
      var cn = new YAHOO.extension.ColumNav('mycolumnav', cn_cfg);
  }
  YAHOO.util.Event.addListener(window, 'load', init);
&lt;/script&gt;
</code></pre>

<p>The ColumNav constructor accepts two arguments: the <code>id</code> of the outermost <code>&lt;div&gt;</code> (the one with <code>class="carousel-component"</code>), and an object containing configuration properties. These properties are name/value pairs governing the ColumNav look and behavior:</p>

<ul>
<li><strong>source:</strong> (required) a string representing the URL to call via Ajax in order to load the initial items, <strong>OR</strong> a reference to a DOM object containing the necessary list structure</li>
<li><strong>prevElement:</strong> (optional) a string or array of strings corresponding to the <code>id</code>(s) of the "back" button(s). Can also be a DOM object or array of DOM objects. <strong>Note:</strong> this property was named <code>prevId</code> in previous releases, but renamed to be consistent with the Carousel documentation. <code>prevId</code> is still recognized for backward compatibility.</li>
<li><strong>linkAction:</strong> (optional) a reference to a function to be called whenever a leaf node link is clicked. This function should return <code>true</code> or <code>false</code> depending on whether or not the link <code>href</code> should be followed in normal fashion after the function has completed. It should accept a single argument: the event that triggered the link.</li>
<li><strong>numVisible:</strong> (optional) an integer representing the number of visible columns (defaults to 1).</li>
</ul>

<p>A ColumNav instance exports a single public method: <code>reset()</code> which can be called at any time to revert the component back to its original state.</p>

<h3>CSS</h3>

<p>Two stylesheets are required:</p>

<pre><code>&lt;link href="carousel.css" rel="stylesheet" type="text/css"/&gt;
&lt;link href="columnav.css" rel="stylesheet" type="text/css"/&gt;
</code></pre>

<p>The <code>carousel.css</code> file governs the layout and behavior of the underlying Carousel component, and should not be edited. The <code>columnav.css</code> file can be edited to customize the look and feel of the ColumNav component. Apart from altering fonts, colors, margins, etc., rules can be added to display different icons for each list item type. When the script runs, it introduces three additional CSS class names which you can use to refine the display:</p>

<ul>
<li><strong>columnav-has-menu:</strong> designates an item that, when clicked, will produce a sub-menu</li>
<li><strong>columnav-active:</strong> designates an item that has been clicked</li>
<li><strong>columnav-error:</strong> designates an error message (occurs when an Ajax request fails)</li>
</ul>

<p>In addition to these class names, others can be added to an item by including them in the source document, providing fine-grained CSS control. For example:</p>

<pre><code>&lt;ul&gt;
    &lt;li&gt;&lt;a href="examples/ajax/ncaa/index.xml" class="ncaa" rel="ajax"&gt;NCAA&lt;/a&gt;&lt;li&gt;
&lt;/ul&gt;
</code></pre>

<p>When loaded into the ColumNav, the link above will contain two class names: "ncaa" (propagated from the source content), and "columnav-has-menu" (due to the presence of <code>rel="ajax"</code>). This allows you to display a different icon based on the given class name. For example:</p>

<pre><code>.carousel-component ul.carousel-list li a.ncaa span {
    background-image: url(ncaa-logo.png);
}
</code></pre>

<p>Note the background image belongs to the nested <code>span</code>.</p>

<p>It is important to remember that the content source markup is not copied verbatim into the ColumNav. Instead, it is transformed into a format more suitable for containment within the Carousel component. For instance, when the markup above is translated into the Carousel (e.g. <code>#mycolumnav ul.carousel-list</code>) it looks like this:</p>

<pre><code>&lt;li&gt;
  &lt;div&gt;
    &lt;a href="examples/ajax/ncaa/index.xml" class="ncaa columnav-has-menu"&gt;NCAA&lt;/a&gt;
  &lt;div&gt;
&lt;/li&gt;
</code></pre>

<p>Keep this in mind when styling the ColumNav.</p>

<h2>Tips</h2>

<ul>
<li><p>When the ColumNav has focus, you can use the keyboard to navigate the menus. Hold down the <kbd>CTRL</kbd> key while pressing the arrow keys (the <kbd>CTRL</kbd> key prevents the browser from performing the default action for the arrow keys: scrolling the main browser window).</p></li>
<li><p>When viewing the Ajax examples above or developing your own, be sure to view the pages from a web server instead of locally, or else the connections will fail. Also, be sure that your Ajax responses return XML content, that is, are served with an XML mime type such as <code>application/xml</code>. Some browsers will not treat the response as XML without a proper mime type.</p></li>
<li><p>If having an empty <code>&lt;ul&gt;</code> element in your ColumNav HTML offends your standard-compliant sensibilities, you can insert an empty <code>&lt;li&gt;</code> if you'd like. But make sure you remove it before instantiating the ColumNav, or it might not render properly.</p></li>
<li><p>In Internet Explorer, you might notice the images flickering slightly when you mouse over them. To remedy this, add the following code at the top of your script:</p>

<pre><code>try { document.execCommand('BackgroundImageCache', false, true); } catch(e) {}
</code></pre>

<p>See <a href="http://evil.che.lu/2006/9/25/no-more-ie6-background-flicker">http://evil.che.lu/2006/9/25/no-more-ie6-background-flicker</a> for more information.</p></li>
</ul>

<h2>Credits</h2>

<p>My name is <a href="http://stringify.com/">David Lindquist</a>, and I wrote the ColumNav JavaScript, CSS, examples, and this documentation. Many thanks to <a href="http://looksgoodworkswell.com/">Bill Scott</a> for his wonderful Carousel component upon which ColumNav is based, and to the Yahoo UI developers for my favorite JavaScript framework. Special thanks go to <a href="http://markupmonkey.com/">Nate Steiner</a> for suggesting the ColumNav name, and for convincing me to allow for non-Ajax content loading.</p>

<p>Questions? Comments? Send me email at stringify.com, username: david.</p>

<!-- Markdown generated HTML ends here -->
      </div>
    </div>
  </body>
</html>
